游标 cursor

1.1 作用
用来存放多条数据的一个结果集

1.2 游标的使用步骤

使用步骤
定义游标
    declare 
            cursor 游标名 is select语句;
    begin
打开游标
    open 游标名;
提取数据 操作数据
    fatch 游标名 into 变量
关闭游标
    close 游标名;

1.3 举例

查询 s_emp表中 id first_name salary 放入一个游标中 然后提取游标中前两条数据并进行打印。

declare
    cursor empcursor is select id,first_name,salary from s_emp;
    type emptype is record(
        id s_emp.id%type,
        first_name s_emp.first_name%type,
        salary s_emp.salary%type
    );
    var_emp emptype;
begin
    oper empcursor;
    fetch empcursor into var_emp;
    dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);
    fetch  empcursor into  var_emp;   
    dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);  
    close empcursor;
end;
/
------------------------------------------------------------------------------------------
   declare
      cursor  empcursor is  select id,first_name,salary from s_emp;  
      var_emp   empcursor%rowtype;
       begin
      open  empcursor;
      fetch  empcursor into  var_emp;
      dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary); 
      fetch  empcursor into  var_emp;   
      dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);  
      close  empcursor;   
       end;
       /  

1.4 如何提取游标中所有的数据

游标的属性
游标名%found      当提取游标数据时  如果提取到了新数据 则这个属性返回true   如果没有提取到
      新数据 则这个属性返回false。但这个属性使用有两个前提 第一游标必须处于打开状态 否则返回
      非法游标  第二 游标必须fetch  否则这个属性返回 null值。
游标名%notfound     当提取游标数据时  如果提取到了新数据 则这个属性返回false   如果没有提取到
      新数据 则这个属性返回true。但这个属性使用有两个前提 第一游标必须处于打开状态 否则返回
      非法游标  第二 游标必须fetch  否则这个属性返回 null值。

简单循环 结合notfound属性
declare
    cursor  empcursor is  select id,first_name,salary from s_emp;  
    var_emp   empcursor%rowtype;
begin
    open empcursor;
    loop
        fetch empcurror into var_emp;
        /* 提取不到新数据时 结束循环 */
        exit when epmcursor%notfound;
        dbms_output.put_line(var_emp.id||':'||var_emp.first_name||var_emp.salary);
    end loop;
    close empcursor;
end;
/
------------------------------------------------------------------------------------------
把上面的游标遍历 改成 使用 while 循环  结合 found 属性遍历
   declare
      cursor  empcursor is  select id,first_name,salary from s_emp;  
      var_emp   empcursor%rowtype;
   begin
          open  empcursor;
          fetch  empcursor into  var_emp;   
          while  empcursor%found loop        
                 dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);  
                 fetch  empcursor into  var_emp;
          end  loop;
          close  empcursor;   
   end;
   / 
------------------------------------------------------------------------------------------
for 询函 遍历游标
for循环又叫智能循环 它可以自动定义变量 自动打开游标 自动提取数据 自动关闭游标

   declare
          cursor  empcursor is  select id,first_name,salary from s_emp;  
   begin
          for  var_emp in empcursor  loop        
                 dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);  
          end  loop;   
   end;
   / 

1.5 游标的其它属性

游标名 % isopen   判断游标是否处于打开状态  打开的游标返回  true   关闭的游标返回false.
     注意打开的游标不能再打开   关闭的游标不能再关闭。

 游标名 % rowcount   游标指针偏移量  (了解)
      游标必须打开 否则报错   游标指针默认在第一条数据之前

1.6 带参游标

定义游标时 可以给游标 设计参数
游标的参数 可以在游标对应的查询语句中使用
只要在打开游标时 传入实参即可
注意:plsql 中 参数不能加长度修饰 但是可以使用%type

   declare
          cursor  empcursor(var_id   s_emp.id%type) is  select id,first_name,salary 
                  from s_emp where  id>var_id;  
          var_emp   empcursor%rowtype;
   begin
          open  empcursor(20);
          loop        
                 fetch  empcursor into  var_emp;   
                 /* 提取不到新数据时 结束循环  */
                  exit  when  empcursor%notfound; 
                 dbms_output.put_line(var_emp.id||':'||var_emp.first_name||':'||var_emp.salary);  
          end  loop;
          close  empcursor;   
   end;
   /  
------------------------------------------------------------------------------------------
 for 循环能否 遍历带参游标  
 declare
        cursor  empcursor(var_id   s_emp.id%type) is  select id,first_name,salary 
                from s_emp where  id>var_id;  
 begin
        for   var_emp  in  empcursor(15)   loop
                dbms_output.put_line(var_emp.id||':'||var_emp.first_name);
        end  loop;
 end;
   /  

1.7 把每个员工的 名字 和 对应部门编号 以及 部门的名字 放入一个游标中

然后提取这个游标中的所有数据 打印

  declare
         cursor   empdeptcursor  is  select   first_name,dept_id,name from 
                s_emp,s_dept where dept_id=s_dept.id;
  begin
         for  var_t    in  empdeptcursor  loop
                dbms_output.put_line(var_t.first_name||':'||var_t.dept_id||':'||var_t.name);
         end loop;                 
  end;
  / 
------------------------------------------------------------------------------------------
把每个员工的 员工编号 名字  和  对应部门编号  以及 部门的名字 放入一个游标中 然后提取这个游标中的所有数据 打印 

  declare
         cursor   empdeptcursor  is  select  s_emp.id eid, first_name,dept_id,name,s_dept.id did from  s_emp,s_dept where dept_id=s_dept.id;
  begin
         for  var_t    in  empdeptcursor  loop
                dbms_output.put_line(var_t.eid||':'||var_t.first_name||':'||var_t.dept_id
                ||':'||var_t.name);
         end loop;                 
  end;
  /